#define rGPA0CON  (*(volatile unsigned int *)0xE0200000)
#define rUCON0  	 (*(volatile unsigned int *)0xE2900004)  //发送和接受都是轮训模式，
#define rULCON0   (*(volatile unsigned int *)0xE2900000)  //0校验位 8数据位 1停止位  普通模式(非红外模式） 

#define rUMCON0   (*(volatile unsigned int *)0xE290000C)    //禁止modem, afc
#define rUFCON0   (*(volatile unsigned int *)0xE2900008)    //禁止FIFO模式

#define rUBRDIV0  (*(volatile unsigned int *)0xE2900028)  //和波特率有关，需要计算
#define rUDIVSLOTO (*(volatile unsigned int *)0xE290002c)  //和波特率有关，需要计算

#define rUTRSTAT0 (*(volatile unsigned int *)0xE2900010)  //
#define rUTXH0 (*(volatile unsigned int *)0xE2900020)  //
#define rURXH0 (*(volatile unsigned int *)0xE2900024)  //
	

//串口初始化程序
void uart_init(void){
	//初始化Tx, Rx对应的GPIO引脚
	rGPA0CON &=~(0xff);
	rGPA0CON |= 0x22;

	//几个关键寄存器设置
	rULCON0 =0x3;
	rUCON0= 0x5;
	rUMCON0 = 0;
	rUFCON0=0;

	//波特率设置  DIV_VAL =(PCLK / (bps *16)) -1
	// PCKK_PSYS 用 66.6MHz计算， 余数 0.8
	rUBRDIV0 = 35;

	// rUDIVSLOTO中的1的个数/16 =上一步计算的余数0.18
	rUDIVSLOTO= 0x0888; //3个一，查官方推荐表得到这个数字
}

//串口发送程序，发送一个字节
void putc(char c){
	//因为串口控制器发送一个字节速度远远低于CPU的速度，所以CPU发送一个字节之前必须确认串口控制器当前缓冲区是空的

	//如果缓冲区非空则位为0，此时应该循环
	while( !(rUTRSTAT0 & (1<<1) ) );

	//串口发送一个字节，就是把这个值写入发送缓冲区
	rUTXH0 = c;
}

//串口接受程序，轮训方式，接受一个字节
char getc(void){
	while( !(rUTRSTAT0 & (1<<0) ) );

	//串口发送一个字节，就是把这个值写入发送缓冲区
	return (rURXH0 &0x0f);
} 